package controllers;

import authentication.IMembershipProvider;
import authentication.annotations.Auth;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import entities.ProductStatus;
import entities.ProductType;
import entities.ProductsEntity;
import managers.WrongBidException;
import models.BidInfo;
import models.HomePageModel;
import models.ProductModel;
import services.ProductsService;

import java.util.Date;

import static br.com.caelum.vraptor.view.Results.json;

//http://java.dzone.com/articles/java-web-application-security-1
//http://shiro-user.582556.n2.nabble.com/Shiro-Jdbc-Realm-Mysql-td6519616.html

//http://vraptor.caelum.com.br/en/docs/dependency-injection/

@Resource
public class HomeController extends BaseController {
    private final ProductsService productsService;

    public HomeController(Result result, IMembershipProvider membershipProvider, ProductsService productsService) {
        super(result, membershipProvider);

        this.productsService = productsService;
    }

    @Get("/")
    public HomePageModel index() {
        //Subject currentUser = SecurityUtils.getSubject();
        HomePageModel model = new HomePageModel(productsService.getProductsManager().getProducts());
        return model;
    }

    @Auth
    @Get("/product/{id}")
    public ProductModel product(Integer id){
        if(id == null){
            result.redirectTo(HomeController.class).index();
            return null;
        }

        ProductsEntity product = productsService.getProductsManager().getProductById(id);
        if(product == null){
            result.redirectTo(HomeController.class).index();
            return null;
        }

        ProductModel viewModel = new ProductModel(product);

        boolean isAdmin = isAdmin();

        if(product.getType() == ProductType.AUCTION || isAdmin) {
            viewModel.setBids(productsService.getProductsManager().getBids(product.getId()));
            viewModel.setBidAvailable(!isAdmin && product.getStatus() == ProductStatus.NORMAL);
        } else {
            Date now = new Date();
            viewModel.setBids(productsService.getProductsManager().getBids(product.getId(), getUserName()));
            viewModel.setBidAvailable(!isAdmin &&
                    product.getStatus() == ProductStatus.NORMAL &&
                    product.getDateEnd().after(now));
        }

        viewModel.setMinBid(product.getMinPrice());

        if(product.getType() == ProductType.AUCTION) {
            for(BidInfo bid : viewModel.getBids()) {
                if(viewModel.getMinBid() < bid.getPrice()){
                    viewModel.setMinBid(bid.getPrice());
                }
            }
        }

        return viewModel;
    }

    @Auth
    @Post
    public void bid(int productId, float price){
        try {
            productsService.placeBid(productId, getUserName(), price);
        } catch (WrongBidException e) {
            result.use(json()).from(e.getMessage()).serialize();
            return;
        }

        result.use(json()).from("Succeed").serialize();
    }
}
